﻿using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using iemtm.WeChat.Core.Extension;
using iemtm.WeChat.Core.Model;
using iemtm.WeChat.Core.Util;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace iemtm.WeChat.Core.Managers
{
    public class GeneratorManager : IGeneratorManager, IScoped
    {
        private readonly IRepository<ReportRecord> _reportRecordRepository;
        private readonly IRepository<Generator> _generatorRepository;

        private readonly IRepository<CollectorBracket> _collectorBracketRepository;
        private readonly IRepository<CollectorBracketPicture> _collectorBracketPictureRepository;

        private readonly IRepository<CollectorRepair> _collectorRepairRepository;
        private readonly IRepository<CollectorRepairPicture> _collectorRepairPictureRepository;

        private readonly IRepository<Maintenence> _maintenenceRepository;
        private readonly IRepository<Collector> _collectorRepository;



        public GeneratorManager(IRepository<ReportRecord> reportRecordRepository
            , IRepository<CollectorBracket> collectorBracketRepository
            , IRepository<CollectorBracketPicture> collectorBracketPictureRepository
            , IRepository<CollectorRepair> collectorRepairRepository
            , IRepository<CollectorRepairPicture> collectorRepairPictureRepository
            , IRepository<Maintenence> maintenenceRepository
            , IRepository<Generator> generatorRepository
            , IRepository<Collector> collectorRepository
            )
        {
            _reportRecordRepository = reportRecordRepository;
            _collectorBracketRepository = collectorBracketRepository;
            _collectorBracketPictureRepository = collectorBracketPictureRepository;
            _collectorRepairRepository = collectorRepairRepository;
            _collectorRepairPictureRepository = collectorRepairPictureRepository;
            _maintenenceRepository = maintenenceRepository;
            _generatorRepository = generatorRepository;
            _collectorRepository = collectorRepository;
        }

        /// <summary>
        /// 获取发电瞬态记录
        /// </summary>
        /// <param name="rptType">类型</param>
        /// <param name="dtuId">dtuid</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns></returns>
        public async Task<ReportRecord> GetReportRecordFirstAsync(int rptType, string dtuId, DateTime startTime, DateTime endTime)
        {
            return await _reportRecordRepository.FirstOrDefaultAsync(u => u.RptType == rptType && u.dtuId == dtuId && u.RptTime >= startTime && u.RptTime <= endTime);
        }

        /// <summary>
        /// 添加油机
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Generator> AddGeneratorAsync(Generator input)
        {
            return (await _generatorRepository.InsertAsync(input)).Entity;
        }
        /// <summary>
        /// 添加采集器
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Collector> AddCollectorAsync(Collector input)
        {
            return (await _collectorRepository.InsertAsync(input)).Entity;
        }
        /// <summary>
        /// 修改采集器
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Collector> UpdateCollectorAsync(Collector input)
        {
            return (await _collectorRepository.UpdateAsync(input)).Entity;
        }
        /// <summary>
        /// 机组Code的生成
        /// </summary>
        /// <returns></returns>
        public string MakeGeneratorCode(string PrjCode)
        {
            string sql = "";

            //直接寻找最大的AreaCode,然后加1
            int maxAnnId = 0;
            sql = "SELECT MAX( GeneratorId)  FROM dbo.Generator ";
            DataTable dt = sql.SqlQuery();
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0][0] != null &&
                int.TryParse(dt.Rows[0][0].ToString(), out maxAnnId))
            {
                string genCode = "";
                for (long iCount = (maxAnnId + 1) % 100000000; iCount < 100000000; iCount++)
                {
                    genCode = PrjCode + "-" + new Random().Next(6, 99).ToString("D2") + (iCount).ToString("D8");
                    sql = "select 1 from Generator where  GeneratorCode='" + genCode + "'";
                    dt = sql.SqlQuery();
                    if (dt == null || dt.Rows.Count <= 0)
                        return genCode;
                }
                return "";
            }
            return DateTime.Now.ToString("yyyyMMdd") + "-" + new Random().Next(6, 99).ToString("D2") + (1).ToString("D8");
        }

        /// <summary>
        /// 模块自检
        /// </summary>
        /// <param name="dtuId"></param>
        /// <param name="prjcode">登录人prjcode</param>
        /// <returns></returns>
        public async Task<SelfCheckInfo> GetSelfCheckInfoByDtuId(string dtuId,string prjcode)
        {
            DateTime dtS = DateTime.Now;
            SelfCheckInfo m = new SelfCheckInfo();
            if (string.IsNullOrEmpty(dtuId)) return m;
            Collector dev = MemoryEntity.cBuffColl[dtuId];// BllHelper.cBuff[dtuId];
            if (dev == null || !dev.BOnline.Value) return m;

            try
            {
                //再实时获取最新的油量值进行覆盖
                List<CodeValuePair> prs = new List<CodeValuePair>();
                prs.Add(new CodeValuePair { code = "LiBATVolt" });
                prs.Add(new CodeValuePair { code = "ExtBatVolt" });
                prs.Add(new CodeValuePair { code = "GPSposition" });

                List<CodeValuePair> rPairs =await CommLocal.ReadParas(prs, dtuId, 10);
                if (rPairs != null && rPairs.Count > 0)
                {
                    m.BCommOK = true;
                    m.CommSecs = (DateTime.Now - dtS).TotalSeconds;
                  
                    double dtmp = 0;
                    double dtmp2 = 0;
                    if (rPairs.Count >= 2 && rPairs[0].code.ToUpper() == "LiBATVolt".ToUpper() && Common.GetFirstDouble(rPairs[0].value, ref dtmp)
                        && rPairs[1].code.ToUpper() == "ExtBatVolt".ToUpper() && Common.GetFirstDouble(rPairs[1].value, ref dtmp2))
                    {
                        m.BatteryVolt = dtmp;
                        if (dtmp2 > 1) //充电时
                        {
                            Hashtable ht = Common.GetSettingValues("ChargingVal,FullVol1,Coefficient1", prjcode);
                            if (ht != null && ht.Count >= 3)
                            {
                                dtmp = ((double)ht["FullVol1"] - m.BatteryVolt) / (double)ht["Coefficient1"];
                                dtmp = 1 - dtmp;
                                if (dtmp < 0)
                                    dtmp = 0;
                                dtmp = dtmp * 100;
                                m.BatteryPercent = (int)dtmp;
                                m.BBatteryOK = m.BatteryPercent >= (int)(double)ht["ChargingVal"];
                            }
                        }
                        else    //未充电时
                        {
                            Hashtable ht = Common.GetSettingValues("NoChargingVal,FullVol2,Coefficient2", prjcode);
                            if (ht != null && ht.Count >= 3)
                            {
                                dtmp = ((double)ht["FullVol2"] - m.BatteryVolt) / (double)ht["Coefficient2"];
                                dtmp = 1 - dtmp;
                                if (dtmp < 0)
                                    dtmp = 0;
                                dtmp = dtmp * 100;
                                m.BatteryPercent = (int)dtmp;
                                m.BBatteryOK = m.BatteryPercent >= (int)(double)ht["NoChargingVal"];
                            }
                        }
                    }

                    if (rPairs.Count >= 3 && rPairs[2].code.ToUpper() == "GPSposition".ToUpper())
                    {
                        string gpsStr = rPairs[2].value;
                        decimal dLat = 0;
                        decimal dLgt = 0;

                        if (!string.IsNullOrEmpty(gpsStr) && gpsStr.Contains("V"))
                        {
                            System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"[\d],[E|W][\d]{3,5}.[\d]+,[N|S][\d]{3,4}.[\d]{4}");

                            System.Text.RegularExpressions.Match mt = r.Match(gpsStr);
                            if (mt.Success && !string.IsNullOrEmpty(mt.Value)) gpsStr = mt.Value;

                        }
                        if (!string.IsNullOrEmpty(gpsStr) && Common.GetGPSWeiduAndJingdu660D(gpsStr, ref dLat, ref dLgt))
                        {
                            m.BLocationOK = true;
                            m.Latitude = (double)dLat;
                            m.Longitude = (double)dLgt;
                        }
                    }
                }

                return m;
            }
            catch (Exception e)
            {
                return m;
            }
        }

        #region 采集器 保养-与图片
        /// <summary>
        /// 获取采集器保养信息和图片
        /// </summary>
        /// <param name="MaintId">MaintId</param>
        /// <returns></returns>
        public async Task<MaintenenceDetailedModel> GetGenMainAndPritureAsync(int MaintId)
        {

            MaintenenceDetailedModel model = new MaintenenceDetailedModel();
            Maintenence cr = await _maintenenceRepository.SingleAsync(i => i.MaintId == MaintId);
            model.Maintenence = cr;
            model.State = model.Maintenence.IsAudited == null ? "待审核" :
                             (bool)model.Maintenence.IsAudited ? "审核通过" : "审核不通过";
            if (!string.IsNullOrEmpty(model.Maintenence.MaintPicture))
            {
                model.Picture = model.Maintenence.MaintPicture.StringSplitTirm("data:image/jpeg;base64,");
            }
            return model;
        }

        /// <summary>
        /// 获取保养运行时长
        /// </summary>
        /// <returns></returns>
        public async Task<double> GetGenMainRunTimeAsync(string GensetNum,string PrjCode)
        {
            string sql = $"SELECT RunTime-MaintenanceTime AS allRunTime FROM dbo.GeneratorRunTime WHERE GensetNum='{GensetNum}'AND PrjCode = '{PrjCode}'";
            var AllGen =await sql.SqlQueryAsync();
            double RunTime = Convert.ToDouble(AllGen.Rows[0][0].ToString());
            return RunTime;

        }
        /// <summary>
        /// 判断油机保养是否有一条没有审核的
        /// </summary>
        /// <param name="GensetNum"></param>
        /// <returns></returns>
        public async Task<bool> GetGenMainIsAuditedAnyAsync(string GensetNum )
        {
            var IsExits = await _maintenenceRepository.Where(i => i.GensetNum == GensetNum && (i.IsAudited == false || i.IsAudited == null)).AnyAsync();

            return IsExits;
        }
        /// <summary>
        /// 添加采集器保养记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Maintenence> AddMaintenenceAsync(Maintenence input)
        {
            return (await _maintenenceRepository.InsertAsync(input)).Entity;
        }

        


        #endregion

        #region 采集器维修-与图片
        /// <summary>
        /// 获取采集器维修信息和图片
        /// </summary>
        /// <param name="Code">Code</param>
        /// <returns></returns>
        public async Task<CollectorRepairDetailedModel> GetCollectorRepairAndPritureAsync(string Code)
        {

            CollectorRepairDetailedModel model = new CollectorRepairDetailedModel();
            CollectorRepair cr = await _collectorRepairRepository.SingleAsync(i => i.RepairCode == Code);
            CollectorRepairPicture[] crp = _collectorRepairPictureRepository.Where(i => i.RepairCode == Code).ToList().ToArray();
            model.cr = cr;
            model.crp = crp;
            if (cr.AuditState == 0)
                model.State = "未审核";
            if (cr.AuditState == 1)
                model.State = "审核通过";
            if (cr.AuditState == 2)
                model.State = "审核不通过";
            return model;
        }

        /// <summary>
        /// 该采集器存在未审核或审核通过维修的工单
        /// </summary>
        /// <param name="DTUID"></param>
        /// <returns></returns>
        public async Task<bool> GetMaintainAnyAsync(string DTUID)
        {
            return await _collectorRepairRepository.Where(c => c.DTUID == DTUID && (c.AuditState == 0 || c.AuditState == 1)).AnyAsync();
        }
        /// <summary>
        /// 获取维修数据list
        /// </summary>
        /// <param name="DTUID"></param>
        /// <param name="AuditState">状态</param>
        /// <returns></returns>
        public async Task<List<CollectorRepair>> GetMaintainListAsync(string DTUID, int AuditState = -1)
        {
            if (AuditState != -1)
            {
                return await _collectorRepairRepository.Where(x => x.DTUID == DTUID && x.AuditState == AuditState).OrderByDescending(u => u.CreateTime).ToListAsync();
            }
            else
            {
                return  await _collectorRepairRepository.Where(x => x.DTUID == DTUID).OrderByDescending(u => u.CreateTime).ToListAsync();
            }
        }

        /// <summary>
        /// 获取维修数据list
        /// </summary>
        /// <param name="DTUID"></param>
        /// <param name="CreateTime">大于创建时间的</param>
        /// <returns></returns>
        public async Task<List<CollectorRepair>> GetMaintainByCreateTimeListAsync(string DTUID, DateTime CreateTime)
        {
            return await _collectorRepairRepository.Where(x => x.DTUID == DTUID&&x.CreateTime> CreateTime).OrderByDescending(u => u.CreateTime).ToListAsync();
        }

        /// <summary>
        /// 添加采集器维修记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CollectorRepair> AddMaintainAsync(CollectorRepair input)
        {
            return (await _collectorRepairRepository.InsertAsync(input)).Entity;
        }
        /// <summary>
        /// 添加采集器图片维修记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CollectorRepairPicture> AddMaintainPictureAsync(CollectorRepairPicture input)
        {
            return (await _collectorRepairPictureRepository.InsertAsync(input)).Entity;
        }


        /// <summary>
        /// 生成维修工单
        /// </summary>
        /// <returns></returns>
        public string GetRepairCode()
        {
            string sql = "";

            //直接寻找最大的AreaCode,然后加1
            int maxId = 0;
            sql = "select max(Id) from CollectorRepair ";
            DataTable dt = sql.SqlQuery();
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0][0] != null &&
                int.TryParse(dt.Rows[0][0].ToString(), out maxId))
            {
                string repairCode = "";
                for (int iCount = (maxId + 1) % 1000000; iCount < 1000000; iCount++)
                {
                    repairCode = "SFS-" + DateTime.Now.ToString("yyyyMMdd") + "-" + new Random().Next(1, 99).ToString("D2") + iCount.ToString("D6");
                    sql = "select 1 from CollectorRepair where  RepairCode='" + repairCode + "'";
                    dt = sql.SqlQuery();
                    if (dt == null || dt.Rows.Count <= 0)
                        return repairCode;
                }
                return "";
            }
            return "SFS-" + DateTime.Now.ToString("yyyyMMdd") + "-" + new Random().Next(1, 99).ToString("D2") + (1).ToString("D6");
        }
        #endregion

        #region  支架-图片
        /// <summary>
        /// 查询支架
        /// </summary>
        /// <param name="DTUID">油机DTUID</param>
        /// <param name="AuditState">支架审核状态</param>
        /// <returns></returns>
        public async Task<List<CollectorBracket>> GetCollectorBracketAsync(string DTUID,int AuditState)
        {
            return await _collectorBracketRepository.Where(u => u.DTUID == DTUID && u.AuditState == AuditState).ToListAsync();
        }

        /// <summary>
        /// 获取支架信息和图片
        /// </summary>
        /// <param name="BracketCode">支架Code</param>
        /// <returns></returns>
        public async Task<CollectorBracketDetailedModel> GetCollectorBracketAndPritureAsync(string BracketCode)
        {

            CollectorBracketDetailedModel model = new CollectorBracketDetailedModel();
             CollectorBracket cr= await _collectorBracketRepository.SingleAsync(i => i.BracketCode == BracketCode);
            CollectorBracketPicture[] crp = _collectorBracketPictureRepository.Where(i => i.BracketCode == BracketCode).ToList().ToArray();
            model.cr = cr;
            model.crp = crp;
            if (cr.AuditState == 0)
                model.State = "未审核";
            if (cr.AuditState == 1)
                model.State = "审核通过";
            if (cr.AuditState == 2)
                model.State = "审核不通过";
            return model;
        }

        /// <summary>
        /// 统计同个机组支架申请的数量
        /// </summary>
        /// <param name="DTUID"></param>
        /// <returns></returns>
        public async Task<int> GetCollectorBracketCountAsync(string DTUID)
        {
            return await _collectorBracketRepository.Where(u => u.DTUID == DTUID).CountAsync();
        }
        /// <summary>
        /// 添加支架
        /// </summary>
        /// <param name="cb"></param>
        /// <returns></returns>
        public async Task<CollectorBracket> AddCollectorBracketAsync(CollectorBracket  cb)
        {
           
            return (await _collectorBracketRepository.InsertAsync(cb)).Entity;
        }
        /// <summary>
        /// 添加支架图片
        /// </summary>
        /// <param name="cb"></param>
        /// <returns></returns>
        public async Task<CollectorBracketPicture> AddCollectorBracketPictureAsync(CollectorBracketPicture cb)
        {

            return (await _collectorBracketPictureRepository.InsertAsync(cb)).Entity;
        }
        

        /// <summary>
        /// 生成支架工单
        /// </summary>
        /// <returns></returns>
        public string GetBracketCode()
        {
            string sql = "";

            //直接寻找最大的AreaCode,然后加1
            int maxId = 0;
            sql = "select max(Id) from CollectorBracket ";
            DataTable dt =sql.SqlQuery(); ;
            if (dt != null && dt.Rows.Count > 0 && dt.Rows[0][0] != null &&
                int.TryParse(dt.Rows[0][0].ToString(), out maxId))
            {
                string repairCode = "";
                for (int iCount = (maxId + 1) % 1000000; iCount < 1000000; iCount++)
                {
                    repairCode = "SKS-" + DateTime.Now.ToString("yyyyMMdd") + "-" + new Random().Next(1, 99).ToString("D2") + iCount.ToString("D6");
                    sql = "select 1 from CollectorBracket where  BracketCode='" + repairCode + "'";
                    dt = sql.SqlQuery();
                    if (dt == null || dt.Rows.Count <= 0)
                        return repairCode;
                }
                return "";
            }
            return "SKS-" + DateTime.Now.ToString("yyyyMMdd") + "-" + new Random().Next(1, 99).ToString("D2") + (1).ToString("D6");
        }

        #endregion


    }
}
